#include "SDockingButton.h"

#include <core/ImageMgr.h>
#include <core/StyleMgr.h>

#include <QEvent>
#include <QStylePainter>

SDockingButton::SDockingButton(QWidget* buddy, Qt::Alignment align,
                               QWidget* parent /*= nullptr*/)
    : QWidget(parent), m_buddy(buddy), m_align(align), m_parent(parent) {
  if (m_align == Qt::AlignLeft || m_align == Qt::AlignRight)
    setFixedSize(8, 40);
  else if (m_align == Qt::AlignTop || m_align == Qt::AlignBottom)
    setFixedSize(40, 8);
  else
    Q_ASSERT(false && "Align Wrong!");

  m_parent->installEventFilter(this);
  Q_ASSERT(buddy && parent);
  raise();
}

void SDockingButton::setExpand(bool v) {}

bool SDockingButton::eventFilter(QObject* watched, QEvent* event) {
  if (event->type() == QEvent::Resize) {
    updatePos();
  }

  return QWidget::eventFilter(watched, event);
}

void SDockingButton::updatePos() {
  if (m_expand) {
    switch (m_align) {
      case Qt::AlignRight: {
        int x = m_buddy->geometry().left();
        int y = m_parent->geometry().height() / 2 - 20;
        move(x, y);
      } break;
      case Qt::AlignLeft: {
        int x = m_buddy->geometry().right() - 8;
        int y = m_parent->geometry().height() / 2 - 20;
        move(x, y);
      } break;
      case Qt::AlignTop: {
        int x = m_parent->geometry().width() / 2 - 20;
        int y = m_buddy->geometry().bottom() / 2 - 8;
        move(x, y);
      } break;
      case Qt::AlignBottom: {
        int x = m_parent->geometry().width() / 2 - 20;
        int y = m_buddy->geometry().top();
        move(x, y);
      } break;
      default:
        break;
    }
  } else {
    switch (m_align) {
      case Qt::AlignRight: {
        int x = m_parent->geometry().width() - 8;
        int y = m_parent->geometry().height() / 2 - 20;
        move(x, y);
      } break;
      case Qt::AlignLeft: {
        int x = 0;
        int y = m_parent->geometry().height() / 2 - 20;
        move(x, y);
      } break;
      case Qt::AlignTop: {
        int x = m_parent->geometry().width() / 2 - 20;
        int y = 0;
        move(x, y);
      } break;
      case Qt::AlignBottom: {
        int x = m_parent->geometry().width() / 2 - 20;
        int y = m_parent->geometry().height() - 8;
        move(x, y);
      } break;
      default:
        break;
    }
  }
  update();
}

void SDockingButton::mousePressEvent(QMouseEvent* event) {
  m_expand = !m_expand;
  m_buddy->setVisible(m_expand);
  updatePos();
}

void SDockingButton::enterEvent(QEvent* event) {
  m_hover = true;
  update();
}

void SDockingButton::leaveEvent(QEvent* event) {
  m_hover = false;
  update();
}

void SDockingButton::paintEvent(QPaintEvent* event) {
  QColor bkClr = StyleMgr::instance().color(m_hover ? "Hover" : "ButtonNormal");
  QStylePainter painter(this);
  painter.setPen(Qt::NoPen);
  painter.setBrush(bkClr);
  painter.drawRoundedRect(rect(), 2, 2);

  QString imgName;

  switch (m_align) {
    case Qt::AlignRight:
      imgName = m_expand ? "widgets_angle_bracket_right"
                         : "widgets_angle_bracket_left";
      break;
    case Qt::AlignLeft:
      imgName = m_expand ? "widgets_angle_bracket_left"
                         : "widgets_angle_bracket_right";
      break;
    case Qt::AlignTop:
      imgName = m_expand ? "widgets_angle_bracket_top"
                         : "widgets_angle_bracket_bottom";
      break;
    case Qt::AlignBottom:
      imgName = m_expand ? "widgets_angle_bracket_bottom"
                         : "widgets_angle_bracket_top";
      break;
    default:
      break;
  }

  SImage* img = ImgMgr::instance().image(imgName);
  if (!img) return;

  int x = rect().center().x() - img->width() / 2;
  int y = rect().center().y() - img->height() / 2;
  painter.drawImage(x, y, *img);
}
